package org.ehe.finance.voucher.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.ehe.business.project.domain.ProjectEntity;
import org.ehe.business.project.service.ProjectService;
import org.ehe.business.supplier.domain.SupplierInfo;
import org.ehe.business.supplier.service.SupplierInfoService;
import org.ehe.common.core.exception.ServiceException;
import org.ehe.common.mybatis.core.page.PageQuery;
import org.ehe.common.mybatis.core.page.TableDataInfo;
import org.ehe.common.satoken.utils.LoginHelper;
import org.ehe.finance.currency.domain.ErpFinanceCurrency;
import org.ehe.finance.currency.service.ErpFinanceCurrencyService;
import org.ehe.finance.customer.domain.ErpFinanceCustomer;
import org.ehe.finance.customer.mapper.ErpFinanceCustomerMapper;
import org.ehe.finance.customer.service.ErpFinanceCustomerService;
import org.ehe.finance.subject.domain.ErpFinanceAccountSubject;
import org.ehe.finance.subject.service.ErpFinanceAccountSubjectService;
import org.ehe.finance.voucher.domain.ErpFinanceVoucher;
import org.ehe.finance.voucher.domain.ErpFinanceVoucherDetail;
import org.ehe.finance.voucher.domain.bo.*;
import org.ehe.finance.voucher.domain.vo.ErpFinanceVoucherDetailVo;
import org.ehe.finance.voucher.mapper.ErpFinanceVoucherDetailMapper;
import org.ehe.finance.voucher.mapper.ErpFinanceVoucherMapper;
import org.ehe.finance.voucher.service.ErpFinanceVoucherDetailService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author :zhangnn
 * @className :ErpFinanceVoucherDetailServiceImpl
 * @description: TODO
 * @date 2025-08-25 13:34:33
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ErpFinanceVoucherDetailServiceImpl extends ServiceImpl<ErpFinanceVoucherDetailMapper, ErpFinanceVoucherDetail>
    implements ErpFinanceVoucherDetailService {

    private final ErpFinanceVoucherDetailMapper voucherDetailMapper;
    private final ErpFinanceAccountSubjectService subjectService;
    private final ErpFinanceCurrencyService currencyService;
    private final SupplierInfoService supplierInfoService;

    private final ErpFinanceVoucherMapper voucherMapper;
    private final ProjectService projectService;
    private final ErpFinanceCustomerMapper customerMapper;

    /**
     * 分页
     * @param bo 查询条件
     * @param pageQuery 分页参数
     * @return
     */
    @Override
    public TableDataInfo<ErpFinanceVoucherDetailVo> pageVoucherDetails(VoucherDetailQueryBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<ErpFinanceVoucherDetail> lqw = new LambdaQueryWrapper<>();
        lqw.eq(bo.getVoucherId() != null, ErpFinanceVoucherDetail::getVoucherId, bo.getVoucherId())
            .eq(bo.getSubjectId() != null, ErpFinanceVoucherDetail::getSubjectId, bo.getSubjectId())
            .eq(bo.getCustomerId() != null, ErpFinanceVoucherDetail::getCustomerId, bo.getCustomerId())
            .eq(bo.getSupplierId() != null, ErpFinanceVoucherDetail::getSupplierId, bo.getSupplierId())
            .eq(bo.getEmployeeId() != null, ErpFinanceVoucherDetail::getEmployeeId, bo.getEmployeeId())
            .eq(bo.getProjectId() != null, ErpFinanceVoucherDetail::getProjectId, bo.getProjectId())
            .eq(bo.getDepartmentId() != null, ErpFinanceVoucherDetail::getDepartmentId, bo.getDepartmentId())
            .eq(bo.getCurrencyId() != null, ErpFinanceVoucherDetail::getCurrencyId, bo.getCurrencyId())
            .ge(bo.getDebitAmountMin() != null, ErpFinanceVoucherDetail::getDebitAmount, bo.getDebitAmountMin())
            .le(bo.getDebitAmountMax() != null, ErpFinanceVoucherDetail::getDebitAmount, bo.getDebitAmountMax())
            .ge(bo.getCreditAmountMin() != null, ErpFinanceVoucherDetail::getCreditAmount, bo.getCreditAmountMin())
            .le(bo.getCreditAmountMax() != null, ErpFinanceVoucherDetail::getCreditAmount, bo.getCreditAmountMax())
            .like(StrUtil.isNotBlank(bo.getAbstractKeyword()), ErpFinanceVoucherDetail::getAbstractInfo, bo.getAbstractKeyword())
            .orderByAsc(ErpFinanceVoucherDetail::getVoucherId)
            .orderByAsc(ErpFinanceVoucherDetail::getEntryNo);

        IPage<ErpFinanceVoucherDetailVo> result = voucherDetailMapper.selectVoPage(pageQuery.build(), lqw);
        result.getRecords().forEach(r->{
            ErpFinanceAccountSubject subject = subjectService.getById(r.getSubjectId());
            r.setSubjectCode(subject.getSubjectCode());
            r.setSubjectName(subject.getSubjectName());
            r.setSubjectLevel(subject.getSubjectLevel());

            ErpFinanceVoucher voucher = voucherMapper.selectById(r.getVoucherId());
            r.setVoucherNo(voucher.getVoucherNo());

            ErpFinanceCurrency currency = currencyService.getById(r.getCurrencyId());
            if(Objects.nonNull(currency)){
                r.setCurrencyCode(currency.getCurrencyCode());
                r.setCurrencyName(currency.getCurrencyName());
            }
            SupplierInfo supplierInfo = supplierInfoService.getById(r.getSupplierId());
            r.setSupplierName(supplierInfo.getSupplierName());

            //项目名称
            ProjectEntity project = projectService.getById(r.getProjectId());
            if(Objects.nonNull(project)){
                r.setProjectName(project.getProjectName());
            }
            //客户名称
            ErpFinanceCustomer customer = customerMapper.selectById(r.getCustomerId());
            if(Objects.nonNull(customer)){
                r.setCustomerName(customer.getCustomerName());
            }

            // 设置方向和金额
            if (r.getDebitAmount() != null && r.getDebitAmount().compareTo(BigDecimal.ZERO) > 0) {
                r.setDirection("借");
                r.setAmount(r.getDebitAmount());
            } else if (r.getCreditAmount() != null && r.getCreditAmount().compareTo(BigDecimal.ZERO) > 0) {
                r.setDirection("贷");
                r.setAmount(r.getCreditAmount());
            }
        });
        return TableDataInfo.build(result);
    }

    /**
     * 创建凭证明细
     * @param createBo 创建对象
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createVoucherDetail(VoucherDetailCreateBo createBo) {
        Integer nextEntryNo = this.getNextEntryNo(createBo.getVoucherId());
        createBo.setEntryNo(nextEntryNo);
        // 检查凭证是否存在且状态是否允许修改
        checkVoucherEditableStatus(createBo.getVoucherId());

        // 验证借贷方金额
        validateDebitCreditAmount(createBo.getDebitAmount(), createBo.getCreditAmount());

        ErpFinanceVoucherDetail entity = new ErpFinanceVoucherDetail();
        BeanUtil.copyProperties(createBo, entity);
        entity.setTenantId(LoginHelper.getTenantId());
        entity.setCreateDept(LoginHelper.getDeptId());

        if (save(entity)) {
            // 更新凭证主表金额合计
            voucherMapper.updateVoucherTotals(createBo.getVoucherId());

            log.info("创建凭证明细成功，ID: {}, 凭证ID: {}", entity.getId(), createBo.getVoucherId());
            return entity.getId();
        }

        throw new ServiceException("创建凭证明细失败");
    }

    /**
     * 更新凭证明细
     * @param updateBo 更新对象
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateVoucherDetail(VoucherDetailUpdateBo updateBo) {
        ErpFinanceVoucherDetail existEntity = getById(updateBo.getId());
        if (existEntity == null) {
            throw new ServiceException("凭证明细不存在");
        }

        // 检查凭证是否存在且状态是否允许修改
        checkVoucherEditableStatus(existEntity.getVoucherId());

        // 验证借贷方金额
        validateDebitCreditAmount(updateBo.getDebitAmount(), updateBo.getCreditAmount());

        BeanUtil.copyProperties(updateBo, existEntity, "id", "voucherId");

        if (!updateById(existEntity)) {
            throw new ServiceException("更新凭证明细失败");
        }

        // 更新凭证主表金额合计
       voucherMapper.updateVoucherTotals(existEntity.getVoucherId());

        log.info("更新凭证明细成功，ID: {}", updateBo.getId());
    }

    /**
     * 删除凭证明细
     * @param id 明细ID
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteVoucherDetail(Long id) {
        ErpFinanceVoucherDetail entity = getById(id);
        if (entity == null) {
            throw new ServiceException("凭证明细不存在");
        }

        // 检查凭证是否存在且状态是否允许修改
        checkVoucherEditableStatus(entity.getVoucherId());

        if (!removeById(id)) {
            throw new ServiceException("删除凭证明细失败");
        }

        // 更新凭证主表金额合计
        voucherMapper.updateVoucherTotals(entity.getVoucherId());

        log.info("删除凭证明细成功，ID: {}", id);
    }

    /**
     * 批量删除凭证明细
     * @param ids 明细ID列表
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchDeleteVoucherDetails(List<Long> ids) {
        if (CollectionUtil.isEmpty(ids)) {
            return;
        }

        // 获取涉及的凭证ID列表
        List<ErpFinanceVoucherDetail> details = listByIds(ids);
        List<Long> voucherIds = details.stream()
            .map(ErpFinanceVoucherDetail::getVoucherId)
            .distinct()
            .collect(Collectors.toList());

        for (Long id : ids) {
            deleteVoucherDetail(id);
        }

        // 批量更新涉及的凭证金额合计
        for (Long voucherId : voucherIds) {
            voucherMapper.updateVoucherTotals(voucherId);
        }
    }

    /**
     * 凭证明细详情
     * @param id 明细ID
     * @return
     */
    @Override
    public ErpFinanceVoucherDetailVo getVoucherDetailById(Long id) {
        ErpFinanceVoucherDetail entity = getById(id);
        if (entity == null) {
            throw new ServiceException("凭证明细不存在");
        }

        return convertToVO(entity);
    }

    /**
     * 根据凭证ID获取明细列表
     * @param voucherId 凭证ID
     * @return
     */
    @Override
    public List<ErpFinanceVoucherDetailVo> getDetailsByVoucherId(Long voucherId) {
        return voucherDetailMapper.selectDetailsByVoucherId(voucherId);
    }

    /**
     * 批量获取凭证明细
     * @param voucherIds
     * @return
     */
    @Override
    public List<ErpFinanceVoucherDetailVo> getDetailsByVoucherIds(List<Long> voucherIds) {
        if (CollectionUtil.isEmpty(voucherIds)) {
            return new ArrayList<>();
        }
        return voucherDetailMapper.selectDetailsByVoucherIds(voucherIds);
    }

    /**
     * 批量保存凭证明细
     * @param batchSaveBo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchSaveVoucherDetails(VoucherDetailBatchSaveBo batchSaveBo) {
        Long voucherId = batchSaveBo.getVoucherId();
        List<VoucherDetailCreateBo> details = batchSaveBo.getDetails();

        // 检查凭证是否存在且状态是否允许修改
        checkVoucherEditableStatus(voucherId);

        // 验证明细数据
        ValidateResult validateResult = validateDetails(details);
        if (!validateResult.isValid()) {
            throw new ServiceException("明细数据验证失败：" + validateResult.getMessage());
        }

        // 删除原有明细
        deleteDetailsByVoucherId(voucherId);

        // 插入新明细
        List<ErpFinanceVoucherDetail> entities = new ArrayList<>();
        for (int i = 0; i < details.size(); i++) {
            VoucherDetailCreateBo createBo = details.get(i);
            ErpFinanceVoucherDetail entity = new ErpFinanceVoucherDetail();
            BeanUtil.copyProperties(createBo, entity);
            entity.setVoucherId(voucherId);
            entity.setEntryNo(i + 1); // 重新编号
            entity.setTenantId(LoginHelper.getTenantId());
            entity.setCreateDept(LoginHelper.getDeptId());
            entities.add(entity);
        }

        if (!saveBatch(entities)) {
            throw new ServiceException("批量保存凭证明细失败");
        }

        // 更新凭证主表金额合计
        voucherMapper.updateVoucherTotals(voucherId);

        log.info("批量保存凭证明细成功，凭证ID: {}, 明细数量: {}", voucherId, entities.size());
    }

    /**
     * 删除凭证的所有明细
     * @param voucherId
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteDetailsByVoucherId(Long voucherId) {
        int count = voucherDetailMapper.deleteByVoucherId(voucherId);
        log.info("删除凭证明细，凭证ID: {}, 删除数量: {}", voucherId, count);
    }

    /**
     * 凭证合计金额
     */
    @Override
    public ErpFinanceVoucherDetailMapper.VoucherTotalAmount getVoucherTotalAmount(Long voucherId) {
        return voucherDetailMapper.getVoucherTotalAmount(voucherId);
    }

    /**
     * 验证凭证借贷平衡
     * @param voucherId
     * @return
     */
    @Override
    public boolean validateVoucherBalance(Long voucherId) {
        return voucherDetailMapper.checkVoucherBalance(voucherId);
    }

    /**
     * 获取下一个分录号
     * @param voucherId
     * @return
     */
    @Override
    public Integer getNextEntryNo(Long voucherId) {
        Integer maxEntryNo = voucherDetailMapper.getMaxEntryNo(voucherId);
        return (maxEntryNo == null ? 0 : maxEntryNo) + 1;
    }

    /**
     * 根据科目查询明细
     * @param subjectId
     * @param startDate
     * @param endDate
     * @return
     */
    @Override
    public List<ErpFinanceVoucherDetailVo> getDetailsBySubject(Long subjectId, LocalDate startDate, LocalDate endDate) {
        return voucherDetailMapper.selectDetailsBySubject(subjectId, startDate, endDate);
    }

    /**
     * 根据辅助核算查询明细
     * @param customerId
     * @param supplierId
     * @param employeeId
     * @param projectId
     * @param departmentId
     * @param startDate
     * @param endDate
     * @return
     */
    @Override
    public List<ErpFinanceVoucherDetailVo> getDetailsByAuxiliary(Long customerId, Long supplierId,
                                                                 Long employeeId, Long projectId,
                                                                 Long departmentId, LocalDate startDate,
                                                                 LocalDate endDate) {
        return voucherDetailMapper.selectDetailsByAuxiliary(customerId, supplierId, employeeId,
            projectId, departmentId, startDate, endDate);
    }

    /**
     * 统计科目发生额
     * @param subjectIds
     * @param startDate
     * @param endDate
     * @return
     */
    @Override
    public List<VoucherDetailStatBo> getSubjectAmountStat(List<Long> subjectIds, LocalDate startDate, LocalDate endDate) {
        if (CollectionUtil.isEmpty(subjectIds)) {
            return new ArrayList<>();
        }
        return voucherDetailMapper.getSubjectAmountStat(subjectIds, startDate, endDate);
    }

    @Override
    public List<ErpFinanceVoucherDetailMapper.VoucherDetailSummary> getVoucherDetailSummary(Long voucherId) {
        return voucherDetailMapper.getVoucherDetailSummary(voucherId);
    }

    @Override
    public BigDecimal getSubjectBalance(Long subjectId, LocalDate endDate) {
        return voucherDetailMapper.getSubjectBalance(subjectId, endDate);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void copyVoucherDetails(Long sourceVoucherId, Long targetVoucherId) {
        List<ErpFinanceVoucherDetail> sourceDetails = list(new LambdaQueryWrapper<ErpFinanceVoucherDetail>()
            .eq(ErpFinanceVoucherDetail::getVoucherId, sourceVoucherId)
            .orderByAsc(ErpFinanceVoucherDetail::getEntryNo));

        if (CollectionUtil.isEmpty(sourceDetails)) {
            return;
        }

        List<ErpFinanceVoucherDetail> targetDetails = new ArrayList<>();
        for (ErpFinanceVoucherDetail sourceDetail : sourceDetails) {
            ErpFinanceVoucherDetail targetDetail = new ErpFinanceVoucherDetail();
            BeanUtil.copyProperties(sourceDetail, targetDetail, "id", "createTime", "updateTime", "createBy", "updateBy");
            targetDetail.setVoucherId(targetVoucherId);
            targetDetail.setTenantId(LoginHelper.getTenantId());
            targetDetail.setCreateDept(LoginHelper.getDeptId());
            targetDetails.add(targetDetail);
        }

        if (!saveBatch(targetDetails)) {
            throw new ServiceException("复制凭证明细失败");
        }

        log.info("复制凭证明细成功，源凭证ID: {}, 目标凭证ID: {}, 明细数量: {}",
            sourceVoucherId, targetVoucherId, targetDetails.size());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void reorderEntryNos(Long voucherId) {
        List<ErpFinanceVoucherDetail> details = list(new LambdaQueryWrapper<ErpFinanceVoucherDetail>()
            .eq(ErpFinanceVoucherDetail::getVoucherId, voucherId)
            .orderByAsc(ErpFinanceVoucherDetail::getCreateTime));

        for (int i = 0; i < details.size(); i++) {
            ErpFinanceVoucherDetail detail = details.get(i);
            detail.setEntryNo(i + 1);
            updateById(detail);
        }

        log.info("重新排序分录号成功，凭证ID: {}, 明细数量: {}", voucherId, details.size());
    }

    @Override
    public List<ErpFinanceVoucherDetailVo> getMultiCurrencyDetails(Long voucherId) {
        return voucherDetailMapper.selectMultiCurrencyDetails(voucherId);
    }

    @Override
    public ValidateResult validateDetails(List<VoucherDetailCreateBo> details) {
        if (CollectionUtil.isEmpty(details)) {
            return new ValidateResult(false, "明细列表不能为空");
        }

        if (details.size() < 2) {
            return new ValidateResult(false, "至少需要2条分录");
        }

        BigDecimal totalDebit = BigDecimal.ZERO;
        BigDecimal totalCredit = BigDecimal.ZERO;
        List<String> errors = new ArrayList<>();

        for (int i = 0; i < details.size(); i++) {
            VoucherDetailCreateBo detail = details.get(i);

            // 验证科目
            if (detail.getSubjectId() == null) {
                errors.add("第" + (i + 1) + "行：会计科目不能为空");
            }

            // 验证借贷方金额
            BigDecimal debit = detail.getDebitAmount() == null ? BigDecimal.ZERO : detail.getDebitAmount();
            BigDecimal credit = detail.getCreditAmount() == null ? BigDecimal.ZERO : detail.getCreditAmount();

            if (debit.compareTo(BigDecimal.ZERO) == 0 && credit.compareTo(BigDecimal.ZERO) == 0) {
                errors.add("第" + (i + 1) + "行：借方和贷方金额不能同时为0");
            }

            if (debit.compareTo(BigDecimal.ZERO) > 0 && credit.compareTo(BigDecimal.ZERO) > 0) {
                errors.add("第" + (i + 1) + "行：借方和贷方金额不能同时有值");
            }

            totalDebit = totalDebit.add(debit);
            totalCredit = totalCredit.add(credit);
        }

        // 验证借贷平衡
        if (totalDebit.compareTo(totalCredit) != 0) {
            errors.add("借贷不平衡：借方合计=" + totalDebit + "，贷方合计=" + totalCredit);
        }

        ValidateResult result = new ValidateResult();
        result.setValid(errors.isEmpty());
        result.setMessage(errors.isEmpty() ? "验证通过" : "验证失败");
        result.setErrors(errors);

        return result;
    }
    /**
     * 计算外币金额
     * @param amount
     * @param exchangeRate
     * @return
     */
    @Override
    public BigDecimal calculateForeignAmount(BigDecimal amount, BigDecimal exchangeRate) {
        if (amount == null || exchangeRate == null) {
            return BigDecimal.ZERO;
        }
        return amount.divide(exchangeRate, 2, RoundingMode.HALF_UP);
    }

    @Override
    public List<ErpFinanceVoucherDetail> generateCounterDetails(Long voucherId, VoucherDetailCreateBo mainDetail) {
        // TODO: 实现自动生成对方科目明细的逻辑
        // 这里可以根据业务规则自动生成对应的借贷方分录
        return new ArrayList<>();
    }

    /**
     * 导出凭证明细
     * @param bo
     * @return
     */
    @Override
    public List<ErpFinanceVoucherDetailVo> exportVoucherDetails(VoucherDetailQueryBo bo) {
        LambdaQueryWrapper<ErpFinanceVoucherDetail> lqw = buildQueryWrapper(bo);
        List<ErpFinanceVoucherDetail> details = list(lqw);
        return details.stream().map(this::convertToVO).collect(Collectors.toList());
    }

    /**
     * 检查凭证是否允许编辑
     */
    private void checkVoucherEditableStatus(Long voucherId) {
        ErpFinanceVoucher voucher = voucherMapper.selectById(voucherId);
        if (voucher == null) {
            throw new ServiceException("凭证不存在");
        }

        if (voucher.getVoucherStatus() != 1) {
            throw new ServiceException("只有制单状态的凭证才能修改明细");
        }
    }

    /**
     * 验证借贷方金额
     */
    private void validateDebitCreditAmount(BigDecimal debitAmount, BigDecimal creditAmount) {
        BigDecimal debit = debitAmount == null ? BigDecimal.ZERO : debitAmount;
        BigDecimal credit = creditAmount == null ? BigDecimal.ZERO : creditAmount;

        if (debit.compareTo(BigDecimal.ZERO) == 0 && credit.compareTo(BigDecimal.ZERO) == 0) {
            throw new ServiceException("借方和贷方金额不能同时为0");
        }

        if (debit.compareTo(BigDecimal.ZERO) > 0 && credit.compareTo(BigDecimal.ZERO) > 0) {
            throw new ServiceException("借方和贷方金额不能同时有值");
        }
    }

    /**
     * 构建查询条件
     */
    private LambdaQueryWrapper<ErpFinanceVoucherDetail> buildQueryWrapper(VoucherDetailQueryBo bo) {
        return new LambdaQueryWrapper<ErpFinanceVoucherDetail>()
            .eq(bo.getVoucherId() != null, ErpFinanceVoucherDetail::getVoucherId, bo.getVoucherId())
            .eq(bo.getSubjectId() != null, ErpFinanceVoucherDetail::getSubjectId, bo.getSubjectId())
            .eq(bo.getCustomerId() != null, ErpFinanceVoucherDetail::getCustomerId, bo.getCustomerId())
            .eq(bo.getSupplierId() != null, ErpFinanceVoucherDetail::getSupplierId, bo.getSupplierId())
            .eq(bo.getEmployeeId() != null, ErpFinanceVoucherDetail::getEmployeeId, bo.getEmployeeId())
            .eq(bo.getProjectId() != null, ErpFinanceVoucherDetail::getProjectId, bo.getProjectId())
            .eq(bo.getDepartmentId() != null, ErpFinanceVoucherDetail::getDepartmentId, bo.getDepartmentId())
            .eq(bo.getCurrencyId() != null, ErpFinanceVoucherDetail::getCurrencyId, bo.getCurrencyId())
            .like(StrUtil.isNotBlank(bo.getAbstractKeyword()), ErpFinanceVoucherDetail::getAbstractInfo, bo.getAbstractKeyword())
            .orderByAsc(ErpFinanceVoucherDetail::getVoucherId)
            .orderByAsc(ErpFinanceVoucherDetail::getEntryNo);
    }

    /**
     * 转换为VO对象
     */
    private ErpFinanceVoucherDetailVo convertToVO(ErpFinanceVoucherDetail entity) {
        ErpFinanceVoucherDetailVo vo = new ErpFinanceVoucherDetailVo();
        BeanUtil.copyProperties(entity, vo);

        // 设置方向和金额
        if (entity.getDebitAmount() != null && entity.getDebitAmount().compareTo(BigDecimal.ZERO) > 0) {
            vo.setDirection("借");
            vo.setAmount(entity.getDebitAmount());
            vo.setForeignAmount(entity.getForeignDebit());
        } else if (entity.getCreditAmount() != null && entity.getCreditAmount().compareTo(BigDecimal.ZERO) > 0) {
            vo.setDirection("贷");
            vo.setAmount(entity.getCreditAmount());
            vo.setForeignAmount(entity.getForeignCredit());
        }

        // TODO: 设置关联信息，如科目信息、辅助核算信息等

        return vo;
    }
}
